All files / src/pages/premium-full [...slug].astro

0% Statements 0/0
0% Branches 0/0
0% Functions 0/0
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163                                                                                                                                                                                                                                                                                                                                     
---
import { getCollection, render } from 'astro:content';
import Layout from '../../layouts/Layout.astro';
import Header from '../../components/Header/index.tsx';
import ShareBox from '../../components/ShareBox/index.tsx';
import Sidebar from '../../components/Sidebar/index.tsx';
import RelatedPosts from '../../components/Relateds/index.tsx';
import TimeToRead from '../../components/TimeToRead/index.tsx';
import TextToSpeech from '../../components/TextToSpeech/index.tsx';
import AuthorBio from '../../components/AuthorBio/index.tsx';
import Breadcrumb from '../../components/Breadcrumb.astro';
import config from '../../config/index.json';
import { parseDate } from '../../utils/index';
 
export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts
    .filter((post) => post.data.premium === true)
    .map((post) => {
      const slug = post.slug;
      return {
        params: { slug },
        props: { post },
      };
    });
}
 
const { post } = Astro.props;
const { Content: PostContent } = await render(post);
 
const rawText = post.body || '';
const speechText = rawText
  .replace(/## Table of Contents[\s\S]*?(?=\n## )/g, '')
  .replace(/```[\s\S]*?```/g, '')
  .replace(/!\[[^\]]*\]\([^)]*\)/g, '')
  .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
  .replace(/`([^`]*)`/g, '$1')
  .replace(/<[^>]+>/g, '')
  .replace(/^#{1,6}\s*/gm, '')
  .replace(/[*_~>]/g, '')
  .replace(/\n{3,}/g, '\n\n')
  .trim();
const wordCount = rawText
  .replace(/```[\s\S]*?```/g, '')
  .replace(/`([^`]*)`/g, '$1')
  .replace(/[#*_\[\]()!]/g, '')
  .replace(/\s+/g, '')
  .length;
const minutes = Math.ceil(wordCount / 400);
 
const slug = post.slug;
const shareURL = `${config.siteUrl}/${slug}/`;
 
const fallbackDescription = rawText
  .replace(/## Table of Contents[\s\S]*?(?=\n## )/g, '')
  .replace(/```[\s\S]*?```/g, '')
  .replace(/!\[[^\]]*\]\([^)]*\)/g, '')
  .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
  .replace(/`([^`]*)`/g, '$1')
  .replace(/<[^>]+>/g, '')
  .replace(/^#{1,6}\s*/gm, '')
  .replace(/[*_~>|]/g, '')
  .replace(/\n+/g, ' ')
  .trim()
  .slice(0, 120);
const postDescription = post.data.description || `${fallbackDescription}...`;
 
const allPosts = await getCollection('blog');
const sorted = allPosts.sort(
  (a, b) => new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
);
 
const latestPosts = sorted.slice(0, 6).map((p) => ({
  title: p.data.title,
  slug: p.slug,
  date: p.data.date.toISOString(),
  url: p.slug,
}));
 
const allPostsForSidebar = sorted.map((p) => ({
  date: p.data.date.toISOString(),
  tags: p.data.tags || [],
}));
 
const allPostsForRelated = sorted.map((p) => ({
  title: p.data.title,
  tags: p.data.tags || [],
  date: p.data.date.toISOString(),
  headerImage: p.data.headerImage,
  slug: `/${p.slug}/`,
}));
---
 
<Layout
  title={post.data.title}
  description={postDescription}
  ogImage={post.data.headerImage || config.defaultImage}
  ogpPath={`/og/${slug}.png`}
  isPostPage={true}
  isPost={true}
  tag={post.data.tags?.[0] || ''}
  canonicalUrl={shareURL}
  datePublished={post.data.date.toISOString()}
  dateModified={(post.data.updatedDate || post.data.date).toISOString()}
  keywords={post.data.tags || []}
  faq={post.data.faq || []}
  noindex={true}
  wordCount={wordCount}
>
  <div class="post row order-2">
    <Header
      client:idle
      img={post.data.headerImage || config.defaultImage}
      title={post.data.title}
      authorName={config.author}
      authorImage={true}
      subTitle={parseDate(post.data.date.toISOString())}
      showCopyMd={false}
    />
    <Sidebar
      client:visible
      latestPosts={latestPosts}
      allPosts={allPostsForSidebar}
      totalCount={sorted.length}
    />
    <main class="col-xl-7 col-lg-6 col-md-12 col-sm-12 order-2">
      <Breadcrumb tag={post.data.tags?.[0] || ''} title={post.data.title} />
      <TimeToRead client:idle words={wordCount} minutes={minutes} />
      <TextToSpeech client:idle text={speechText} />
      {post.data.useAi && (
        <aside style="background:#fffbe6; border-left:4px solid #f0c040; padding:12px; margin-bottom:16px; border-radius:4px;">
          <p>この記事はAIにて執筆を実施したものです。</p>
        </aside>
      )}
      <div class="content-white-inner">
        <PostContent />
      </div>
      <div class="content-white-inner">
        <h2>tubone24にラーメンを食べさせよう!</h2>
        <p>ぽちっとな↓</p>
        <a href="https://www.buymeacoffee.com/tubone24">
          <img
            src="https://img.buymeacoffee.com/button-api/?text=Buy me a ramen&emoji=🍜&slug=tubone24&button_colour=40DCA5&font_colour=ffffff&font_family=Lato&outline_colour=000000&coffee_colour=FFDD00"
            alt="Buy me a ramen"
            width="217"
            height="60"
            loading="lazy"
            decoding="async"
          />
        </a>
      </div>
      <AuthorBio client:idle />
      <RelatedPosts
        client:idle
        title={post.data.title}
        tags={post.data.tags || []}
        allPosts={allPostsForRelated}
      />
    </main>
    <ShareBox client:visible url={shareURL} />
  </div>
</Layout>